package com.flyinzhen.customer.service;

import com.flyinzhen.core.constants.ResponseStatus;
import com.flyinzhen.core.dto.ResponseDto;
import com.flyinzhen.core.utils.CommonUtils;
import com.flyinzhen.customer.constants.CustStatus;
import com.flyinzhen.customer.dto.input.*;
import com.flyinzhen.customer.dto.output.FileUploadOutput;
import com.flyinzhen.customer.entity.*;
import com.flyinzhen.customer.interfaces.IFeignSupportService;
import com.flyinzhen.customer.repository.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * 用户认证实现类
 *
 * @author yinzhen
 * @date 2019-05-01
 */
@Slf4j
@Service
public class CustomerService {

	@Resource
	CustBasicRepository basicRepository;

	@Resource
	CustCompanyRepository companyRepository;

	@Resource
	CustIdCardRepository idCardRepository;

	@Resource
	CustBankCardRepository bankCardRepository;

	@Resource
	CustContactRepository contactRepository;

	@Resource
	CustImageRepository imageRepository;

	@Resource
	IFeignSupportService supportService;

	@Transactional
	public ResponseDto saveBasicInfo(BasicSaveInput inputDto) {
		CustBasicInfo basicInfo = basicRepository.findTopByCustId(inputDto.getUserId()).orElseGet(CustBasicInfo::new);
		if (checkStatus(inputDto.getStatus(), basicInfo.getStatus())) {
			return ResponseDto.status(ResponseStatus.STAGE_INVALID);
		}

		BeanUtils.copyProperties(inputDto, basicInfo);
		basicRepository.save(basicInfo);
		return ResponseDto.ok();
	}

	public ResponseDto getBasicInfo(String userId) {
		return ResponseDto.ok(basicRepository.findTopByCustId(userId).orElseThrow(NoSuchElementException::new));
	}

	@Transactional
	public ResponseDto saveCompanyInfo(CompanySaveInput inputDto) {
		CustCompanyInfo companyInfo = companyRepository.findTopByCustIdAndCompanyName(inputDto.getUserId(),
			inputDto.getCompanyName()).orElseGet(CustCompanyInfo::new);
		if (checkStatus(inputDto.getStatus(), companyInfo.getStatus())) {
			return ResponseDto.status(ResponseStatus.STAGE_INVALID);
		}

		BeanUtils.copyProperties(inputDto, companyInfo);
		companyRepository.save(companyInfo);
		return ResponseDto.ok();
	}

	public ResponseDto getCompanyInfo(String userId) {
		return ResponseDto.ok(companyRepository.findByCustId(userId));
	}

	public ResponseDto saveIdCardInfo(IdCardSaveInput inputDto) {
		CustIdCard idCardInfo = idCardRepository.findTopByCustId(inputDto.getUserId()).orElseGet(CustIdCard::new);
		if (checkStatus(inputDto.getStatus(), idCardInfo.getStatus())) {
			return ResponseDto.status(ResponseStatus.STAGE_INVALID);
		}

		BeanUtils.copyProperties(inputDto, idCardInfo);
		idCardRepository.save(idCardInfo);
		return ResponseDto.ok();
	}

	public ResponseDto getIdCardInfo(String userId) {
		return ResponseDto.ok(idCardRepository.findTopByCustId(userId));
	}

	public ResponseDto saveBankCardInfo(BankCardSaveInput inputDto) {
		CustBankCard bankCardInfo = bankCardRepository.findTopByCustId(inputDto.getUserId()).orElseGet(CustBankCard::new);
		if (checkStatus(inputDto.getStatus(), bankCardInfo.getStatus())) {
			return ResponseDto.status(ResponseStatus.STAGE_INVALID);
		}

		BeanUtils.copyProperties(inputDto, bankCardInfo);
		bankCardRepository.save(bankCardInfo);
		return ResponseDto.ok();
	}

	public ResponseDto getBankCardInfo(String userId) {
		return ResponseDto.ok(bankCardRepository.findTopByCustId(userId));
	}

	public ResponseDto saveContactsInfo(ContactsSaveInput inputDto) {
		List<CustContactInfo> resultInfos = new ArrayList<>();
		List<CustContactInfo> contactInfos = contactRepository.findByCustId(inputDto.getUserId());
		for (ContactSaveInput item : inputDto.getContactSaveInputList()) {
			CustContactInfo contactInfo = contactInfos.parallelStream().filter(i ->
				i.getPhone().equals(item.getPhone())).findAny().orElseGet(CustContactInfo::new);
			BeanUtils.copyProperties(inputDto, contactInfo);
			resultInfos.add(contactInfo);
		}
		contactRepository.saveAll(resultInfos);
		return ResponseDto.ok();
	}

	public ResponseDto getContactsInfo(String userId) {
		return ResponseDto.ok(contactRepository.findByCustId(userId));
	}

    public ResponseDto saveImageInfo(String userId, String fileType, MultipartFile file, String status) {
		ResponseDto uploadResponse = supportService.uploadFile(fileType, file);
		FileUploadOutput uploadOutput = CommonUtils.getResponseBody(uploadResponse, FileUploadOutput.class);

		CustImageInfo imageInfo = new CustImageInfo();
		imageInfo.setCustId(userId);
		imageInfo.setImageId(uploadOutput.getId());
		imageInfo.setImageName(uploadOutput.getFileName());
		imageInfo.setImageType(uploadOutput.getFileType());
		imageInfo.setImageUrl(uploadOutput.getFileUrl());
		imageInfo.setExpireTime(uploadOutput.getExpireTime());
		imageInfo.setStatus(status);
		imageRepository.save(imageInfo);

		return ResponseDto.ok(imageInfo);
	}

	public ResponseDto getImageInfos(String userId) {
		return ResponseDto.ok(imageRepository.findByCustId(userId));
	}

	private boolean checkStatus(String originStatus, String targetStatus) {
		if (CustStatus.AUTHED.name().equals(targetStatus)) {
			return !CustStatus.AUTHED.name().equals(originStatus);
		} else {
			return false;
		}
	}
}
